from Products.Five.browser import BrowserView
from Acquisition import aq_inner
from plone.memoize.instance import memoize
from apkn.resource import logger
from apkn.resource.interfaces import  IResource
from apkn.resource.config import RESOURCESUBJECTS, RESOURCECOUNTRIES,\
     EXCLUDE_SUBJECTS_DISPLAY

from apkn.resource import ResourceMessageFactory as _

RESOURCES_PATH = u'/Plone/apex/web-directory'
RESOURCES_FOLDER_DEPTH = 1
RESOURCES_SUBJECT_INDEX = u'resourcesubject'
RESOURCES_COUNTRY_INDEX = u'country'
RESOURCE_SEARCH_KEY_TEXT = u"SearchableText"
RESOURCE_SEARCH_KEY_COUNTRY = u"SearchCountry"
RESOURCE_SEARCH_KEY_SUBJECT = u"SearchSubject"
RECENT_ITEM_COUNT = 10

class SearchResources(BrowserView):
        """ 
        Custom search view for resources also displays
        also displays resources as a visualization
        """

        def update(self):
                pass

        @memoize
        def getIndexedCountryNames(self):
                current_resource_path = \
                '/'.join(self.context.getPhysicalPath())
                catalog = self.context.portal_catalog
                indexed_countries = []

                resources_folder = aq_inner(self.context)

                selected_value = None
                if self.searchSubmitted():
                        selected_value = self.getFormParameter(RESOURCE_SEARCH_KEY_COUNTRY)

                try:
                        catalog_query = {
                                        'object_provides': IResource.__identifier__,
                                        'path': current_resource_path
                                        }
                        indexed_brains = catalog(catalog_query)
                        if not indexed_brains:
                            #skip language check
                            catalog_query['Language'] = ''
                            indexed_brains = catalog(catalog_query)
                        
                        resource_countries = [o.getObject().country 
                                              for o in indexed_brains]

                        #filter duplicate countries
                        uniques = {}
                        map(uniques.__setitem__, resource_countries, [])
                        #TODO How to deal with Guinea-Bissau
                        unique_countries = uniques.keys()
                        cap_uniques = []
                        for c in unique_countries:
                                country = RESOURCECOUNTRIES.getValue(c)
                                if selected_value == c:
                                        country_data = {'text': country, 'id': c, 
                                                        'selected': u'selected'}
                                else:
                                        country_data = {'text': country, 'id': c, 
                                                        'selected': None}
                                cap_uniques.append(country_data)
                        indexed_countries = cap_uniques
                except:
                        pass
                sorted_countries = sorted(indexed_countries)
                return sorted_countries

        @memoize
        def getResourceSubjects(self):
                catalog = self.context.portal_catalog
                resource_indices_raw = \
                                     catalog.uniqueValuesFor(u"resourcesubjectindex")

                selected_subject = None
                if self.searchSubmitted():
                        selected_subject = \
                                         self.getFormParameter(RESOURCE_SEARCH_KEY_SUBJECT)

                text_indices = []

                #exclude certain subjects from display form
                resource_indices = \
                                 filter(lambda s: s not in EXCLUDE_SUBJECTS_DISPLAY,
                                        resource_indices_raw)

                for index in resource_indices:
                        if type(index) == list:
                                for i in index:
                                        if not i in text_indices:
                                                if len(i):
                                                        text_indices.append(i)
                        else:
                                if len(index):
                                        text_indices.append(index)

                logger.info("Resource subjects found [as text]: %s", 
                            text_indices.__str__())

                resource_subjects = []
                for r_index in resource_indices:
                        try:
                                subject_text = RESOURCESUBJECTS.getValue(r_index)
                                logger.info("Resource subject from display list %s",
                                            subject_text.__str__())

                                selected_value = None
                                if selected_subject == r_index:
                                        selected_value = u'selected'

                                if (not subject_text is None):
                                        subject_meta = {'id': r_index,
                                                        'verbose': subject_text,
                                                        'selected': selected_value}
                                        resource_subjects.append(subject_meta)
                        except:
                                logger.error("Failed to load resource subject index: %s",
                                             r_index)
                sorted_resource_subjects = sorted(resource_subjects,
                                                  key = lambda subject: subject['id'])
                return sorted_resource_subjects

        def searchResults(self):
                search_results = []
                search_country = \
                               self.getFormParameter(RESOURCE_SEARCH_KEY_COUNTRY) 
                search_subject = \
                               self.getFormParameter(RESOURCE_SEARCH_KEY_SUBJECT)
                search_results = self.performSearch(search_country, 
                                                    search_subject)
                object_brains = [s.getObject() for s in search_results]
                result_count = len(object_brains)
                search_message = self.getSearchMessage(result_count)
                search_data = {'search_results': object_brains, 
                               'search_message': search_message}
                return search_data

        def getFormParameter(self, DATA_KEY):
                return self.request.form.get(DATA_KEY, '')

        def getSearchMessage(self, result_count):
                country = self.getFormParameter(RESOURCE_SEARCH_KEY_COUNTRY)
                if country:
                        country = country.replace('-', ' ').title()
                else:
                        country = _(u'all countries')
                search_subject = self.getFormParameter(RESOURCE_SEARCH_KEY_SUBJECT)
                if search_subject:
                        search_subject = RESOURCESUBJECTS.getValue(search_subject)
                else:
                        search_subject = _(u'all subjects')
                search_text = self.getFormParameter(RESOURCE_SEARCH_KEY_TEXT)
                if not search_text:
                        search_text = _(u'all resources')
                search_message = _(u'search_contacts_status_message',
                                   default = u'Your search for "${search_text}" in \
                                   ${country} under category "${search_subject}" yielded ${result_count} hit(s)',
                                   mapping = {u'search_text': search_text, 
                                              u'country': country,
                                              u'result_count': result_count,
                                              u'search_subject': search_subject}
                                   )
                return search_message 


        def performSearch(self, country = None, subject = None):
                brains = None
                catalog = self.context.portal_catalog
                query = {}

                q_path = {'query': RESOURCES_PATH, 
                          'depth': RESOURCES_FOLDER_DEPTH}
                query['path'] = q_path
                query['object_provides'] = IResource.__identifier__
                query['SearchableText'] = self.getFormParameter(RESOURCE_SEARCH_KEY_TEXT)
                query[u'review_state'] = u'published'

                if country:
                        query['resourcecountry'] = country
                if subject:
                        query['resourcesubjectindex'] = subject
                        pass
                logger.info("Performing this query for resources : %s", 
                            query.__str__())
                brains = catalog.searchResults(query)
                if not brains:
                    query[u'Language'] = ''
                    brains = catalog.searchResults(query)
                return brains

        def searchSubmitted(self):
                return self.request.form.has_key(RESOURCE_SEARCH_KEY_COUNTRY)


        @memoize
        def getRecentItems(self):
                catalog = self.context.portal_catalog
                q_path = {'query': RESOURCES_PATH}
                catalog_items = catalog.searchResults(path = q_path,
                                                      review_state = 'published',
                                                      sort_on = 'Date',
                                                      sort_limit = RECENT_ITEM_COUNT,
                                                      object_provides = IResource.__identifier__,
                                                      )
                return [c_item.getObject() for c_item in catalog_items]
